package cn.edu.hit.calculation;

import android.content.Context;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;

public class MainActivity extends AppCompatActivity {

    private GridView gridView;
    private TextView textView;
    private List<String> calItems;

    private String textContent;

    private Stack<Integer> stateStack = new Stack<>();
    private Stack<String> inputStack = new Stack<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textContent = "";

        textView = findViewById(R.id.textView);

        calItems = new ArrayList<>();

        calItems.add(" ");//0
        calItems.add("C");//1
        calItems.add("<—");//2
        calItems.add("%");//3
        calItems.add("7");//4
        calItems.add("8");//5
        calItems.add("9");//6
        calItems.add("*");//7
        calItems.add("4");//8
        calItems.add("5");//9
        calItems.add("6");//10
        calItems.add("-");//11
        calItems.add("1");//12
        calItems.add("2");//13
        calItems.add("3");//14
        calItems.add("+");//15
        calItems.add(" ");//16
        calItems.add("0");//17
        calItems.add(".");//18
        calItems.add("=");//19

        //初始化状态栈
        stateStack.push(0);

        gridView = (GridView) this.findViewById(R.id.gridView);
        gridView.setAdapter(new AdapterImpl(this, calItems));
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                String input = calItems.get(i);


                if (input.equals("=")) {
                    //预处理，分割数字与符号
                    LinkedList<String> elements = spiltNumandOpe(textContent);
                    //TODO显示结果
                    String result = calExpression(elements);
                    if(result.equals( "-0.0")){
                        result = "0.0";
                    }
                    if (result.equals("Infinity")) {
                        textContent = "";
                        result = "除数不应该为0";
                        textView.setText(textContent + result);
                    } else {
                        textView.setText(textContent + "=" + result);
                    }
                    stateStack.clear();
                    inputStack.clear();
                    stateStack.push(0);
                    textContent = "";
                } else if (input.equals("C")) {
                    textContent = "";
                    textView.setText(textContent);
                } else if (input.equals("<—")) {
                    if (stateStack.empty()) {
                        stateStack.push(0);
                    } else if (!stateStack.empty() && !inputStack.empty()) {
                        stateStack.pop();
                        inputStack.pop();
                        textContent = textContent.substring(0, textContent.length() - 1);
                        textView.setText(textContent);
                    }
                } else {
                    Integer nextState = getNextState(input, stateStack.peek());
                    if (nextState == -1) {
                    } else {
                        textContent += input;
                        inputStack.push(input);
                        stateStack.push(nextState);
                        textView.setText(textContent);
                    }
                }
//                textView.setText(textContent);
            }
        });

    }

    private Integer getNextState(String a, Integer state) {
        Integer nextState = -1;
        if ("=".equals(a)) {
            nextState = 6;
            return nextState;
        }
        //0:1-9
        //1:0
        //2:+ * %
        //3: -
        //4: .
        //5: =
        switch (state) {
            case 0:
                if (ClassificationUtil.getClassification(a) == 3) {
                    nextState = 1;
                }
                if (ClassificationUtil.getClassification(a) == 1) {
                    nextState = 5;
                }
                if (ClassificationUtil.getClassification(a) == 0) {
                    nextState = 3;
                }
                break;
            case 1:
                if (ClassificationUtil.getClassification(a) == 1) {
                    nextState = 5;
                }
                if (ClassificationUtil.getClassification(a) == 0) {
                    nextState = 3;
                }
                break;
            case 2:
                if (ClassificationUtil.getClassification(a) == 1 || ClassificationUtil.getClassification(a) == 0) {
                    nextState = 2;
                }
                if (ClassificationUtil.getClassification(a) == 2 || ClassificationUtil.getClassification(a) == 3) {
                    nextState = 4;
                }
                break;
            case 3:
                if (ClassificationUtil.getClassification(a) == 1 || ClassificationUtil.getClassification(a) == 0) {
                    nextState = 3;
                }
                if (ClassificationUtil.getClassification(a) == 4) {
                    nextState = 2;
                }
                if (ClassificationUtil.getClassification(a) == 2 || ClassificationUtil.getClassification(a) == 3) {
                    nextState = 4;
                }
                break;
            case 4:
                if (ClassificationUtil.getClassification(a) == 1) {
                    nextState = 5;
                }
                if (ClassificationUtil.getClassification(a) == 0) {
                    nextState = 3;
                }
                if (ClassificationUtil.getClassification(a) == 3) {
                    nextState = 7;
                }
                break;
            case 5:
                if (ClassificationUtil.getClassification(a) == 4) {
                    nextState = 2;
                }
                if (ClassificationUtil.getClassification(a) == 2 || ClassificationUtil.getClassification(a) == 3) {
                    nextState = 4;
                }
                break;
            case 6:
                if (ClassificationUtil.getClassification(a) == 2 || ClassificationUtil.getClassification(a) == 3) {
                    nextState = 4;
                }
                break;
            case 7:
                if (ClassificationUtil.getClassification(a) == 1) {
                    nextState = 5;
                }
                if (ClassificationUtil.getClassification(a) == 0) {
                    nextState = 3;
                }
            default:
                break;
        }
        return nextState;
    }

    public String calExpression(LinkedList<String> expression) {
        Stack<String> numbers = new Stack<>();
        Stack<String> operation = new Stack<>();

        String number = "";
        String result = "";
        int i = 0;
        while (!expression.isEmpty()) {
            String element = expression.poll();
            if (element.equals("")) {
                continue;
            }
//            if (element.equals("-") && i == 0) {
//                //第一个数字为负数，将0压入操作数栈，-压入运算符栈
//                numbers.push(0 + "");
//                operation.push(element + "");
//            }
            //通过ASCII表判断数字
            if (element.equals("+") || element.equals("-") || element.equals("*") || element.equals("%")) {
                String lastCharacter = "-1";
                operation.push(element);
                while (!operation.empty()) {
                    element = operation.pop();
                    if (!operation.empty()) {
                        lastCharacter = operation.pop();
                    }

                    //如果当前运算符比上次运算符运算级高，则压入符号栈
                    if (lastCharacter.equals("-1") || ((lastCharacter.equals("+") || lastCharacter.equals("-"))
                            && (element.equals("*") || element.equals("%")))) {
                        if (lastCharacter != "-1") {
                            operation.push(lastCharacter);
                        }
                        operation.push(element + "");
                        numbers.push(number);
                        number = "";
                        break;
                    } else {
                        //弹出两个运算数进行计算，进行计算
                        String number1 = numbers.pop();
                        result = calculate(number1, number, lastCharacter.charAt(0));

                        operation.push(element);
                        numbers.push(result);
                        number = "";
                        break;
                    }
                }

            } else {
                number += element;
                if (expression.isEmpty()) {
                    numbers.push(number);
                    number = "";
                }
            }
        }
        i++;
        while (!operation.empty()) {
            //弹出两个运算数进行计算，进行计算
            String number2 = numbers.pop();
            String number1 = numbers.pop();
            result = calculate(number1, number2, operation.pop().charAt(0));

            numbers.push(result);
        }

        return result;
    }

    public LinkedList<String> spiltNumandOpe(String expression) {
        String number = "";

        LinkedList<String> result = new LinkedList<>();

        char lastCha = 'a';

        for (int i = 0; i < expression.length(); i++) {
            char character = expression.charAt(i);

            if ((character <= 57 && character >= 48) || character == '.') {
                number += character;
                if (i == expression.length() - 1) {
                    result.add(number);
                    number = "";
                }
            } else if (character == '+' || character == '-' || character == '*' || character == '%') {
                if ((lastCha == '+' || lastCha == '-' || lastCha == '*' || lastCha == '%' || lastCha == 'a') && (character == '-')) {
                    number += character;
                } else {
                    result.add(number);
                    number = "";
                    result.add(character + "");
                }
            }
            lastCha = character;
        }
        return result;
    }

    public String calculate(String number1, String number2, char character) {
        float result = 0;
        float a = Float.parseFloat(number1);
        float b = Float.parseFloat(number2);
        switch (character) {
            case '+':
                result = a + b;
                break;
            case '-':
                result = a - b;
                break;
            case '*':
                result = a * b;
                break;
            case '%':
                result = a / b;
                break;
            default:
                break;
        }
        return result + "";
    }

    class AdapterImpl extends BaseAdapter {

        private Context context;
        private List<String> items;

        AdapterImpl(Context context, List<String> items) {
            this.context = context;
            this.items = items;
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public Object getItem(int i) {
            return items.get(i);
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            View v = View.inflate(context, R.layout.gridview_item, null);
            TextView tv = (TextView) v.findViewById(R.id.item);
            tv.setText(items.get(i));
            if (i == 3 || i == 7 || i == 11 || i == 15 || i == 14) {
                tv.setBackgroundColor(Color.parseColor("#FF3543AC"));
                tv.setTextColor(Color.parseColor("#ffffff"));
            } else {
                tv.setBackgroundColor(Color.parseColor("#ffffff"));
                tv.setTextColor(Color.parseColor("#000000"));
            }
            return v;
        }
    }
}
